/**
 * @file videocall.h
 *
 */

#ifndef VIDEOCALL_H
#define VIDEOCALL_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
 *      INCLUDES
 *********************/
#ifdef LV_CONF_INCLUDE_SIMPLE
#include "lvgl.h"
#include "lv_ex_conf.h"
#else
#include "../../../lvgl/lvgl.h"
#include "../../../lv_ex_conf.h"
#endif

#if 0
void voip_alarm_ind(void);
#endif
bool voip_connect_check_req(void);
bool watch_voip_suspend_check(void);
void voip_activity_destroy_req(void);
uint8_t voip_get_call_volume(void);

#if USE_LV_WATCH_VIDEOCALL !=0
/*********************
 *      DEFINES
 *********************/
#define TRUE  1
#define FALSE 0
#define ENABLE_VIDEO_SCALE  1
#ifdef USE_WATCH_LITE
#define SCALE_BASE_ON_HEIGHT 1
#endif
#define VOIP_PHONE_TEST  0
#define VOIP_PHONEBOOK_TEST 0
#define VOIP_JUPHOON_TEST 1
#define VOIP_PHONE_RING_OFF_ANIMATION_TIME 0
#define VOIP_PHONE_RING_OFF_CONTINUE_TIME 1500   /*ms*/
#define VOIP_PHONE_NV_VOLUME_OFFSET          0
#define VOIP_PHONE_NV_EMERGENCY_NUM_OFFSET   1
#define VOIP_PHONEBOOK_CONTACTS_MAX_NAME_LEN    NV_CONTACTS_MAX_NAME_LEN
#define VOIP_PHONEBOOK_CONTACTS_MAX_NUMBER_LEN  NV_CONTACTS_MAX_NUMBER_LEN
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((uint8_t) (((c >> 4) & 0xF0) | ((c >> 8) & 0xF)),   \
                                (uint8_t) ((uint32_t)(c & 0xF0)     | ((c & 0xF0) >> 4)), \
                                (uint8_t) ((uint32_t)(c & 0xF)      | ((c & 0xF) << 4)))
#define H263_FMT_QCIF 1
#if H263_FMT_QCIF == 1
#define VIDEO_SOURCE_WIDTH   176
#define VIDEO_SOURCE_HEIGHT  144
#endif

#if (ENABLE_VIDEO_SCALE==0)
#define canvas_width  VIDEO_SOURCE_WIDTH
#define canvas_heigh  VIDEO_SOURCE_HEIGHT
#else
#define canvas_width  LV_HOR_RES   /* 240 */
#define canvas_heigh  LV_VER_RES   /* 240 */
#endif

#define VIDEO_RENDER_PERIOD  50   /* 1000/50=20fps */
#define VIDEO_SIGNAL_CHECK  0
#define VIDEO_SIGNAL_CHECK_PERIOD  1000
#define VIDEO_RAT_CHECK_PERIOD  200
#define VIDEO_CALL_FPS_CHECK_LIMIT 5
/**********************
 *      TYPEDEFS
 **********************/

typedef enum {
    VOIP_PHONE_UI_INCOMING = 0,
    VOIP_PHONE_UI_DIALING,
    VOIP_PHONE_UI_CONNECTED,
} voip_phone_ui_e;

typedef enum
{
    MMI_VOIP_CALL_STATE_NULL     = 0,
    MMI_VOIP_CALL_STATE_ACTIVE   = 1,
    MMI_VOIP_CALL_STATE_HOLDING  = 2,
    MMI_VOIP_CALL_STATE_DIALING  = 3,                                           /* MO call only */
    MMI_VOIP_CALL_STATE_ALERTING = 4,                                           /* MO call only */
    MMI_VOIP_CALL_STATE_INCOMING = 5,                                           /* MT call only */
    MMI_VOIP_CALL_STATE_WAITING  = 6,                                           /* MT call only */
    MMI_VOIP_CALL_STATE_INVALID  = 0xFF
} MMI_VOIP_CALL_STATE_E;

enum voipregisterstate
{
    VOIP_REGISTER_OK = 0,
    VOIP_UNREGISTERING,
    VOIP_REGISTER_FAIL
};

/** H.263 picture size format */
enum voip_h263_fmt {
    VOIP_H263_FMT_SQCIF = 1, /**<  128 x 96  */
    VOIP_H263_FMT_QCIF  = 2, /**<  176 x 144  */
    VOIP_H263_FMT_CIF   = 3, /**<  352 x 288  */
    VOIP_H263_FMT_4CIF  = 4, /**<  704 x 576  */
    VOIP_H263_FMT_16CIF = 5, /**< 1408 x 1152 */
    VOIP_H263_FMT_OTHER = 7,
};

enum local_remote_switch_e {
    VOIP_REMOTE_SWITCH_REMOTE = 0,
    VOIP_REMOTE_SWITCH_LOCAL,
    VOIP_REMOTE_SWITCH_NULL,
};

enum enum_canvas_button_hidden_flag
{
    NOT_HIDDEN,
    HIDDEN
};

typedef struct {
    char contact_name[VOIP_PHONEBOOK_CONTACTS_MAX_NAME_LEN];
    char contact_number[VOIP_PHONEBOOK_CONTACTS_MAX_NUMBER_LEN];
    const void * img_src;
    const void * img_src_small;
    uint8_t contact_type; /*0:administrator, 1:standby administrator, 2: others*/
} voip_phonebook_contact_t;

typedef nv_watch_phonebook_info_t voip_phonebook_t;

typedef struct {
    lv_watch_obj_ext_t lv_watch_obj;
    /*New data for this type */
    uint8_t body_padding_inner;
    uint8_t append_width;
    uint8_t cur_img_id;
    voip_phonebook_t * cur_contact;
    lv_ll_t contact_list;
    lv_obj_t * label_phone_contact;
    lv_obj_t * page_scrl;
    lv_coord_t move_width;
} lv_voip_phonebook_obj_ext_t;

typedef struct {
    MMI_VOIP_CALL_STATE_E state;
    int32_t              index;                    /* Connection Index for use with, eg, AT+CHLD */
    bool                 is_mt;                    /* true if MT call */
    bool                 ring_off;                 /* true if ring off by user */
    bool                 ring_off_timeout;         /* true if ring off timeout */
    bool                 buffer_alarm;
#define VOIP_RING_OFF_TIMER_LEN    1000
    TIMER_ID             ring_off_timer_id;        /* ring off timer */
    char                 number[NV_CONTACTS_MAX_NUMBER_LEN];   /* phone number */
    char                 name[NV_CONTACTS_MAX_NAME_LEN];       /* contact name */
    const void * img_src;
    const void * img_src_small;
    MODEM_VIDEO_CALL_TYPE    voip_call_type;
#define VOIP_CALLREQ_TIMER_LEN    60*1000
    TIMER_ID             callreq_timer_id;         /* callreq timer */
    uint8_t              speaker_volume;           /* speaker volume during call procedure */
} voip_phone_call_params_t;

typedef struct {
    lv_watch_obj_ext_t lv_watch_obj;
    /*New data for this type */
    lv_obj_t * phone_status_label;
    lv_obj_t * phone_animation_obj;
    uint32_t connect_start_time;
    voip_phone_ui_e phone_ui_t;
    enum local_remote_switch_e local_remote_switch_flag;
    enum voip_h263_fmt voiph263fmt;
    lv_obj_t * connect_time;
    lv_obj_t * ring_value_button;
    lv_obj_t * view_switch_button;
    lv_obj_t * ring_off_button;
    enum enum_canvas_button_hidden_flag canvas_button_hidden_flag;
    lv_obj_t * signal_weak_label;
    lv_obj_t * canvas;
} lv_voip_phone_obj_ext_t;

/**********************
 * GLOBAL PROTOTYPES
 **********************/
lv_voip_phone_obj_ext_t * voip_phone_get_ext(void);
void * voip_phone_get_video_buffer(void);
#ifdef USE_WATCH_LITE
void * voip_phone_get_video_trans_buffer(void);
#endif
void watch_voip_call_response_connect(int32_t index);
int get_voipcall_params_index(void);
void watch_voip_call_response_no_carrier(int32_t index, uint8_t isNoCarrier);
void watch_voip_call_response_alerting(int32_t index);
void watch_voip_incomingcall_response(char * number, int32_t calltype);
void watch_voip_call_response_bottom_error(void);
void watch_voip_call_response_bottom_need_redail(void);
bool check_voipcall_enter_pm_ind(void);
void watch_voip_message_handle_init(void);
void watch_ui_voip_message_handle(void * voipmsg);
void watch_voip_autotest_handle(void * testmsg);

void voip_call_init(void);
int8_t voip_call_dial_req(MODEM_VIDEO_CALL_TYPE calltype, char * pContactUri);
void voip_call_hangup_req(BOOL bye);
int8_t voip_call_answer_req(void);
void voip_call_reject_req(BOOL bye);
void voip_fps_check(int8_t fps);
void voip_bt_connected(void);
void voip_ring_off_req(void);

/****************************
 * Create a demo application
 ****************************/
void videocallmain_create(lv_obj_t *btn, lv_event_t e);

/**********************
 *      MACROS
 **********************/
#endif //#if USE_LV_WATCH_VIDEOCALL !=0

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /*VIDEOCALL_H*/
